from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys,os
import numpy as np
import cv2
import commands
import datetime
import time

def mylabel(parent,str,x,y,h=50,w=50):
    label=QLabel(parent)
    label.resize(h,w)
    label.move(x,y)
    label.setPixmap(QPixmap(str) )
    label.setScaledContents(True)
    return label 

def textlabel(parent,text,x,y,h=100,w=100):
    label=QLabel(text,parent)
    label.move(x,y)
    label.resize(QSize(h,w))
    font=QFont()
    font.setPointSize(40)
    label.setFont(font)
    color=QPalette()
    color.setColor(QPalette.WindowText,Qt.white)
    label.setPalette(color)
    
    return label
    
def mybutton(self,str,x,y,h=50,w=50):
    btn=QPushButton(self)
    btn.resize(h,w)
    btn.move(x,y)
    btn.setIcon(QIcon(str))
    btn.setIconSize(QSize( h,w+100) )
    #btn.setFlat(True)
    return btn



class Detect_Win(QMainWindow):
    def __init__(self,parent=None):
        super(Detect_Win,self).__init__(parent)
        self.resize(1150,900)

        #set button box
        btngrouup=labelBox(self,"./detect_img")
        btngrouup.resize(QSize(1020,420) )
        btngrouup.send_btn_path.connect( self.set_img_frombox)
        btngrouup.move(100,0)
        
        #set infor label
        sex_label=mylabel(self,"./config/gender.png",820,420,100,50)
        glasses_label=mylabel(self,"./config/glasses.png",820,500,100,50)
        age_label=mylabel(self,"./config/age.png",820,590,100,50)
        #emotion_label=mylabel(self,"./config/emotion.png",820,680,100,50)

        self.sex_label_infor=textlabel(self,"None",920,390,300,100)
        self.glasses_label_infor=textlabel(self,"None",920,470,300,100)
        self.age_label_infor=textlabel(self,"None",920,560,300,100)
        #self.emotion_label_infor=textlabel(self,"None",920,650,300,100)
        
        #detect and origin img
        self.left_img_path_name="./detect_img/jhrtnr.png"
        self.left_img_label=mylabel(self,"./detect_img/jhrtnr.png", 20, 420,300,350)
        self.right_img_label=mylabel(self,"./detect_img/jhrtnr.png", 500, 420,300,350)
        
        #set config btn
        detect_btn=mybutton(self,"./config/detect.png", 340, 525,146,76)
        detect_btn.clicked.connect(self.process_img)
        
        self.cam_flag=0
        self.l_add_img_btn=mybutton(self,"./config/add_file.png", 60, 780,60,60)
        self.l_add_img_btn.clicked.connect(self.get_img)
        self.l_cam_img_btn=mybutton(self,"./config/camera.png", 240, 780,60,60)
        self.l_cam_img_btn.clicked.connect(self.start_camera)

        
    def set_img_frombox(self,img_path):
        self.left_img_label.setPixmap(QPixmap(img_path) )    
        self.left_img_path_name=img_path
        self.right_img_label.setPixmap(QPixmap(img_path) )

    def get_img(self):        
      fileName = QFileDialog.getOpenFileName(self,  
                                  "sss",  
                                  "./",  
                                  "Image Files(*.png *.jpg *.bmp *.jpeg)") 
      #print fileName[0]
      self.left_img_path_name=fileName[0]
      self.left_img_label.setPixmap(fileName[0] )
      self.right_img_label.setPixmap(fileName[0])

    def process_img(self):
        if(self.cam_flag==1):
        	QMessageBox.warning(self, 'warning',"please close the camera")
        	return 0
        start = datetime.datetime.now()
        #self.emotion_label_infor.setText( str(emotion) ) 
        self.cv_img = cv2.imread(self.left_img_path_name)
        age=self.face_data[14]
        gender=self.face_data[15]
        glasses=self.face_data[16]
        
        if gender==0 :
            self.sex_label_infor.setText( "Female")
        elif gender==1:
            self.sex_label_infor.setText( "male")
        
        if glasses==0 :
            self.glasses_label_infor.setText( "yes")
        elif glasses==1:
            self.glasses_label_infor.setText( "no")

        if age==0 or age==1 or age==2:
            self.age_label_infor.setText(str("child") )
        elif age==3 or age ==4 :
            self.age_label_infor.setText("teenager" )
        elif age==5 or age==6 or age ==7 or age ==8  :
            self.age_label_infor.setText("adult") 
        elif age==9:
            self.age_label_infor.setText("elder")

        for i in range(self.face_cnt.value):
            cv2.rectangle(self.cv_img,(self.face_data[18*i],self.face_data[18*i+1]),(self.face_data[18*i]+self.face_data[18*i+2],self.face_data[18*i+1]+self.face_data[18*i+3]),(255,0,0),2)
            cv2.circle(self.cv_img,(self.face_data[18*i+4],self.face_data[18*i+5]),4,(0,0,255),-1) #left_eye
            cv2.circle(self.cv_img,(self.face_data[18*i+6],self.face_data[18*i+7]),4,(0,0,255),-1) #right_eye
            cv2.circle(self.cv_img,(self.face_data[18*i+8],self.face_data[18*i+9]),4,(0,0,255),-1) #nose
            cv2.circle(self.cv_img,(self.face_data[18*i+10],self.face_data[18*i+11]),4,(0,0,255),-1) #left_mouth
            cv2.circle(self.cv_img,(self.face_data[18*i+12],self.face_data[18*i+13]),4,(0,0,255),-1) #right_mouth

        height, width, bytesPerComponent = self.cv_img.shape
        bytesPerLine = bytesPerComponent * width;
        # Convert to RGB for QImage.
        cv2.cvtColor(self.cv_img, cv2.COLOR_BGR2RGB, self.cv_img)
        self.image = QImage(self.cv_img.data, width, height, bytesPerLine, QImage.Format_RGB888)

        self.testl=QLabel(self)
        mp=QPixmap("add_file")
        self.right_img_label.setPixmap(mp.fromImage(self.image))
        end= datetime.datetime.now()
        print "detect time:", end-start

    def start_camera(self):

        if(self.cam_flag==0):
            self.cam=cv2.VideoCapture(0)
            if( self.cam.isOpened()==1 ):
                print "sucess"
            else:
                QMessageBox.warning(self, 'warning',"please check the camera")
                return 0   
        
            self.cam_flag=1
            self.l_cam_img_btn.setIcon(QIcon("./config/right.png"))
            self.timer=QTimer(self)
            self.count=0
            self.timer.setInterval(500)
            self.timer.start()
            self.timer.timeout.connect(self.get_camera)
        else:
            self.cam.release()  
            self.timer.stop()
            self.cam_flag=0
            #get processes img
            get_la=self.right_img_label.pixmap()
            get_la.save("./cam_img/cam_get_processed.png")
            self.l_cam_img_btn.setIcon(QIcon("./config/camera.png"))
            self.right_img_label.setPixmap(get_la)

    def get_camera(self):
        start = datetime.datetime.now()
        ret,frame=self.cam.read()
        rgb_frame=frame
        height, width, bytesPerComponent = frame.shape
        bytesPerLine = bytesPerComponent * width;
        # Convert to RGB for QImage.
        cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, rgb_frame)
        self.image = QImage(rgb_frame.data, width, height, bytesPerLine, QImage.Format_RGB888)
        mp=QPixmap("add_file")
        #print self.left_img_path_name

        age=self.face_data[14]
        gender=self.face_data[15]
        glasses=self.face_data[16]
        
        if gender==0 :
            self.sex_label_infor.setText( "Female")
        elif gender==1:
            self.sex_label_infor.setText( "male")
        
        if glasses==0 :
            self.glasses_label_infor.setText( "yes")
        elif glasses==1:
            self.glasses_label_infor.setText( "no")

        if age==0 or age==1 or age==2:
            self.age_label_infor.setText(str("child") )
        elif age==3 or age ==4 :
            self.age_label_infor.setText("teenager" )
        elif age==5 or age==6 or age ==7 or age ==8  :
            self.age_label_infor.setText("adult") 
        elif age==9:
            self.age_label_infor.setText("elder")

        for i in range(self.face_cnt.value):
            cv2.rectangle(rgb_frame,(self.face_data[18*i],self.face_data[18*i+1]),(self.face_data[18*i]+self.face_data[18*i+2],self.face_data[18*i+1]+self.face_data[18*i+3]),(255,0,0),2)
            cv2.circle(rgb_frame,(self.face_data[18*i+4],self.face_data[18*i+5]),4,(0,0,255),-1) #left_eye
            cv2.circle(rgb_frame,(self.face_data[18*i+6],self.face_data[18*i+7]),4,(0,0,255),-1) #right_eye
            cv2.circle(rgb_frame,(self.face_data[18*i+8],self.face_data[18*i+9]),4,(0,0,255),-1) #nose
            cv2.circle(rgb_frame,(self.face_data[18*i+10],self.face_data[18*i+11]),4,(0,0,255),-1) #left_mouth
            cv2.circle(rgb_frame,(self.face_data[18*i+12],self.face_data[18*i+13]),4,(0,0,255),-1) #right_mouth
            
        self.right_img_label.setPixmap(mp.fromImage(self.image))
        end= datetime.datetime.now()
        print "camera detect time:",end-start    



class Recognize_Win(QMainWindow):
    def __init__(self,parent=None):
        super(Recognize_Win,self).__init__(parent)
        self.resize(1150,900 )
        
         #set button box
        btngrouup=labelBox(self,"star")
        btngrouup.resize(1020,400 )
        btngrouup.send_btn_path.connect( self.set_img_frombox)
        btngrouup.move(100,0)
        
        self.left_img_path_name="./star/Hugo.png"
        self.left_img_label=mylabel(self,"./star/Hugo.png", 80, 420,300,350) 
        
        self.cam_flag=0
        l_add_img_btn=mybutton(self,"./config/add_file.png", 140, 780,60,60)
        l_add_img_btn.clicked.connect(self.get_img)
        
        self.l_cam_img_btn=mybutton(self,"./config/camera.png", 240, 780,60,60)
        self.l_cam_img_btn.clicked.connect(self.start_camera)
        
        add_btn=mybutton(self,"./config/add.png", 430, 525,146,76)
        add_btn.clicked.connect(self.add_name)
        rec_btn=mybutton(self,"./config/recognize.png", 430, 645,146,76)
        rec_btn.clicked.connect(self.process_img)
        
        result_label=mylabel(self, "./config/result.png", 700, 500, 174,76)
        self.result_label_infor=textlabel(self,"ready",730,600,h=500,w=200)
        
    def add_name(self):
        if self.cam_flag==1:
            QMessageBox.warning(self, 'warning',"please confirm the image from camera")
            return 0

        stringName,ok = QInputDialog.getText(self, "please input name","name",QLineEdit.Normal, "yourname")  
        if(ok):
            print stringName
            tmp=self.left_img_label.pixmap()
            tmp.save("./add_img/%s.png"%stringName)
            self.left_img_path_name ="./add_img/%s.png"%stringName 

            self.result_label_infor.setText( "add sucess" )   
            
    def get_img(self):        
        fileName = QFileDialog.getOpenFileName(self,  
                                    "sss",  
                                    "./",  
                                    "Image Files(*.png *.jpg *.bmp *.jpeg)") 
        self.left_img_label.setPixmap(fileName[0] )
        self.left_img_path_name=fileName[0]
        self.result_label_infor.setText("ready")
        
    def set_img_frombox(self,img_path):
        self.left_img_label.setPixmap(QPixmap(img_path) )
        self.left_img_path_name=img_path
        self.result_label_infor.setText("ready")

#recognize the img from database
    def process_img(self):
        start = datetime.datetime.now()
        if self.cam_flag==1:
            QMessageBox.warning(self, 'warning',"please confirm the image from camera")
            return 0

        self.result_label_infor.setText( face_name  )
        end= datetime.datetime.now()
        print "recognize time:", end-start   

    def start_camera(self):
        if(self.cam_flag==0):
            self.cam=cv2.VideoCapture(0)
            if( self.cam.isOpened()==1 ):
                print "sucess"
            else:
                QMessageBox.warning(self, 'warning',"please check the camera")
                return 0   
        
            self.cam_flag=1
            self.l_cam_img_btn.setIcon(QIcon("./config/right.png"))
            self.result_label_infor.setText("ready")
            self.timer=QTimer(self)
            self.count=0
            self.timer.setInterval(2)
            self.timer.start()
            self.timer.timeout.connect(self.get_camera)
        else:
            self.cam.release()  
            self.timer.stop()
            self.cam_flag=0
            get_la=self.left_img_label.pixmap()
            get_la.save("./cam_img/cam_get.png")
            self.l_cam_img_btn.setIcon(QIcon("./config/camera.png"))
            self.left_img_path_name="./cam_img/cam_get.png" 

    def get_camera(self):
        ret,frame=self.cam.read()
        height, width, bytesPerComponent = frame.shape
        bytesPerLine = bytesPerComponent * width;
        # Convert to RGB for QImage.
        cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame)
        ##modify size 
        self.image = QImage(frame.data, width-30,height , bytesPerLine, QImage.Format_RGB888)
        mp=QPixmap("add_file")
        self.left_img_label.setPixmap(mp.fromImage(self.image))        
        
class Verify_Win(QMainWindow):
    def __init__(self,parent=None):
        super(Verify_Win,self).__init__(parent)
        self.resize(1150,900 )
        
        #set button box
        btngrouup=labelBox(self,"./detect_img")
        btngrouup.resize(1020,420 )
        btngrouup.send_btn_path.connect( self.set_img_frombox)
        btngrouup.move(100,0)
        
        self.left_img_path_name="./detect_img/5ger.png"
        self.left_img_label=mylabel(self,"./detect_img/5ger.png", 80, 420,300,350)
        self.right_img_path_name="./detect_img/aserq2.png"
        self.right_img_label=mylabel(self,"./detect_img/aserq2.png", 560, 420,300,350)  
        
        self.cam_flag=0
        self.l_or_r=0
        l_add_img_btn=mybutton(self,"./config/add_file.png", 140, 780,60,60)
        l_add_img_btn.clicked.connect(self.l_get_img)
        self.l_cam_img_btn=mybutton(self,"./config/camera.png", 240, 780,60,60)
        self.l_cam_img_btn.clicked.connect(self.l_start_camera)

        r_add_img_btn=mybutton(self,"./config/add_file.png", 630, 780,60,60)
        r_add_img_btn.clicked.connect(self.r_get_img)
        self.r_cam_img_btn=mybutton(self,"./config/camera.png", 730, 780,60,60)  
        self.r_cam_img_btn.clicked.connect(self.r_start_camera)
        
        detect_btn=mybutton(self,"./config/verify.png", 400, 555,146,76)
        detect_btn.clicked.connect( self.process_img )
        #set output num
        sim_label=mylabel(self, "./config/similarity.png", 880, 450, 240, 70)
        self.sim_num_test=textlabel(self, "0", 880, 550, 300, 100)
        
    def set_img_frombox(self,img_path):
        self.left_img_label.setPixmap( QPixmap(img_path) )
        self.left_img_path_name=img_path
        
    def l_get_img(self):        
        fileName = QFileDialog.getOpenFileName(self,  
                          "sss",  
                          "./",  
                          "Image Files(*.png *.jpg *.bmp *.jpeg)") 
        self.left_img_label.setPixmap(fileName[0] )

    
    def r_get_img(self):        
        fileName = QFileDialog.getOpenFileName(self,  
                          "sss",  
                          "./",  
                          "Image Files(*.png *.jpg *.bmp *.jpeg)") 
        self.right_img_label.setPixmap(fileName[0] )

    def process_img(self):
        start = datetime.datetime.now()
        if self.cam_flag==1:
            QMessageBox.warning(self, 'warning',"please confirm the image from camera")
            return 0

        print self.left_img_path_name
        print self.right_img_path_name
        
        verify_result=lib.verify_two_face(detector,str(self.left_img_path_name),str(self.right_img_path_name))

        self.sim_num_test.setText( str( verify_result)[0:4] )
        end= datetime.datetime.now()
        print "recognize time:", end-start  

    def l_start_camera(self):
        if(self.cam_flag==0):
            self.cam=cv2.VideoCapture(0)
            if( self.cam.isOpened()==1 ):
                print "sucess"
            else:
                QMessageBox.warning(self, 'warning',"please check the camera")
                return 0   
        
            self.cam_flag=1
            self.l_cam_img_btn.setIcon(QIcon("./config/right.png"))
            self.timer=QTimer(self)
            self.count=0
            self.timer.setInterval(2)
            self.timer.start()
            self.timer.timeout.connect(self.get_camera)
            self.l_or_r=0
        else:
            self.cam.release()  
            self.timer.stop()
            self.cam_flag=0
            get_la=self.left_img_label.pixmap()
            get_la.save("./cam_img/l_cam_get.png")
            self.l_cam_img_btn.setIcon(QIcon("./config/camera.png"))
            self.left_img_path_name="./cam_img/l_cam_get.png" 

    def r_start_camera(self):
        if(self.cam_flag==0):
            self.cam=cv2.VideoCapture(0)
            if( self.cam.isOpened()==1 ):
                print "sucess"
            else:
                QMessageBox.warning(self, 'warning',"please check the camera")
                return 0   
        
            self.cam_flag=1
            self.r_cam_img_btn.setIcon(QIcon("./config/right.png"))
            self.timer=QTimer(self)
            self.count=0
            self.timer.setInterval(2)
            self.timer.start()
            self.timer.timeout.connect(self.get_camera)
            self.l_or_r=1
        else:
            self.cam.release()  
            self.timer.stop()
            self.cam_flag=0
            get_la=self.right_img_label.pixmap()
            get_la.save("./cam_img/r_cam_get.png")
            self.r_cam_img_btn.setIcon(QIcon("./config/camera.png"))
            self.right_img_path_name="./cam_img/r_cam_get.png"

    def get_camera(self):
        ret,frame=self.cam.read()
        height, width, bytesPerComponent = frame.shape
        bytesPerLine = bytesPerComponent * width;
        # Convert to RGB for QImage.
        cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame)
        self.image = QImage(frame.data, width-30, height, bytesPerLine, QImage.Format_RGB888)
        mp=QPixmap("add_file")
        if(self.l_or_r==0):
            self.left_img_label.setPixmap(mp.fromImage(self.image))
        elif(self.l_or_r==1):
            self.right_img_label.setPixmap(mp.fromImage(self.image))

class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super(MainWindow,self).__init__(parent)
        self.setFixedSize(1250,900 ) 
          #set backgroud
        win_bkg=QLabel(self)
        win_bkg.setPixmap(QPixmap("./config/tes.png") )
        self.setCentralWidget(win_bkg)
        
        
        self.setWindowTitle("via")
        listWidget=QListWidget(self)
        listWidget.setResizeMode(QListView.Adjust)
        listWidget.setIconSize(QSize(50, 50))

        func_label=mylabel(self, "./config/func.png", 0, 0,155,42) 
        
        funcAction1=QListWidgetItem(QIcon("./config/a.png"),"face detect" )
        listWidget.insertItem(1, funcAction1)
        
        funcAction1=QListWidgetItem(QIcon("./config/b.png"),"face recognize" )
        listWidget.insertItem(2, funcAction1)
        
        funcAction1=QListWidgetItem(QIcon("./config/c.png"),"face verify" )
        listWidget.insertItem(3, funcAction1)
        
        listWidget.resize(180,180 )
        listWidget.move(0,50)
        
        
        face_detect_win=Detect_Win()
        face_rec_win=Recognize_Win()
        face_ver_win=Verify_Win()
        
        stackWindow=QStackedWidget( self )
        stackWindow.addWidget(face_detect_win)
        stackWindow.addWidget(face_rec_win)
        stackWindow.addWidget(face_ver_win)
        stackWindow.resize(1150,900)
        stackWindow.move(100,0)
        
        self.connect(listWidget,SIGNAL("currentRowChanged(int)"),stackWindow, SLOT("setCurrentIndex(int)") )

class numWidget(QWidget):
    def __init__(self,parent=None):
        super(numWidget,self).__init__(parent) 
        self.pixmapVec=[]
        for i in range(10):
            self.pixmapVec.append(QPixmap("%d.png"%(i)))       
        self.background=QPixmap("examine_score.png")
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.index=[]
        
    def set_num(self,num):
        if num > 99:
            num = 99 
        self.index=[]
        
        if (num >= 10):
            self.index.append(num/10)
            self.index.append(num % 10)
        else:
            self.index.append(num)
            
    def paintEvent(self,env):
        painter=QPainter(self)
        rect=QRect()
        rect=env.rect()

        if (len(self.index)==0 ):
             return 0

        painter.drawPixmap(rect.x(), rect.y(), self.background);
        x = rect.x() + (self.background.width() - self.pixmapVec[0].width()) / 2
        y = rect.y() + (self.background.height() - self.pixmapVec[0].height()) / 2

        if (len(self.index) < 2):   
            painter.drawPixmap(x, y, self.pixmapVec[self.index[0]])
        else:
            
            x = rect.x() + (self.background.width() - 2*self.pixmapVec[0].width()) / 2
            y = rect.y() + (self.background.height() - self.pixmapVec[0].height()) / 2
            painter.drawPixmap(x, y, self.pixmapVec[self.index[0]])
            x += self.pixmapVec[0].width()
            painter.drawPixmap(x, y, self.pixmapVec[self.index[1]])

class labelBox(QWidget):
    send_btn_path=pyqtSignal(str)
    def __init__(self,parent,path):
        super(labelBox,self).__init__(parent)
        path_table=[]
        label_table=[]
        x=0
        y=0
        sigmap=QSignalMapper(self)
        #get img name 
        list = os.listdir(path)
        for line in list:
            filepath = os.path.join(path,line)
            if os.path.isdir(filepath)==0:
                #print filepath
                ext = ['.jpg', '.png']
                if(filepath.endswith( tuple(ext) ) ):
                    path_table.append(filepath) 
                
        #get label table        
        for i in  path_table:
            tmp=self.Boxbutton(i,200,200)
            label_table.append(tmp)  
            
        #config the layout 
        layout=QGridLayout(self)
        for t in label_table:
            layout.addWidget(t,y,x)
            x=x+1
            if(x==7):
                x=0
                y=y+1
        self.setLayout(layout)   
        
        #set signal map
        for index,x in enumerate( label_table ):
            x.clicked.connect(sigmap.map)
            sigmap.setMapping(x, path_table[index] )
            
        #sigmap.mapped[str].connect(self.onClicked )  
        sigmap.mapped[str].connect(self.send_btn_path ) 
        #self.connect(sigmap,SIGNAL("mapped( ) "),self,SLOT("onClicked()"))
        
    @pyqtSlot(str) 
    def onClicked(self,x):
        print x
        
    def Boxbutton(self,str,h=50,w=50):
        btn=QPushButton(self)
        btn.setIcon(QIcon(str))
        btn.setIconSize(QSize( h,w) )
        return btn       
                
            
app=QApplication(sys.argv)
win=QMainWindow()
dlg=labelBox(win,"star")
win.setCentralWidget(dlg)
win.show()
app.exec_()

